package com.cly.cart.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cly.api.clients.ItemClient;
import com.cly.cart.mapper.CartMapper;
import com.cly.cart.service.CartService;
import com.cly.common.entity.cart.dto.CartDTO;
import com.cly.common.entity.cart.po.Cart;
import com.cly.common.entity.cart.vo.CartVO;
import com.cly.common.entity.item.dto.ItemDTO;
import com.cly.common.entity.item.po.Item;
import com.cly.common.entity.result.Result;
import com.cly.common.exception.CommonException;
import com.cly.common.util.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements CartService {
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private ItemClient itemClient;
    /**
     * 添加商品到购物车
     * @param cartDTO
     * @return
     */
    @Override
    public Result addCart(CartDTO cartDTO) {
        Long userId = ThreadLocalUtil.get();
        // 判断该商品是否已经存在于购物车中
        if (checkItemExist(userId, cartDTO.getItemId())) {
            // 已经存在于购物车中，将购物车中的数量加1
            LambdaUpdateWrapper<Cart> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Cart::getUserId, userId)
                    .eq(Cart::getItemId, cartDTO.getItemId())
                    .setSql("cart_num = cart_num + 1");
            try {
                this.update(updateWrapper);
                log.info("购物车商品数量已增加: 用户ID={}, 商品ID={}", userId, cartDTO.getItemId());
                return Result.success();
            } catch (Exception e) {
                throw new CommonException("添加购物车失败",e);
            }
        }
        // 不存在于购物车中，添加进购物车
        Cart cart = BeanUtil.copyProperties(cartDTO, Cart.class);
        cart.setUserId(userId);
        try {
            this.save(cart);
            return Result.success();
        } catch (Exception e) {
            throw new CommonException("添加购物车失败",e);
        }
    }

    /**
     * 获取购物车信息
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Result getCart(Integer pageNum, Integer pageSize) {
        // 先获取购物车信息
        Page<Cart> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Cart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Cart::getUserId, ThreadLocalUtil.get());
        Page<Cart> cartPage = this.page(page, queryWrapper);
        // 把获取到的cart数据转换成cartVO
        List<Cart> cartList = cartPage.getRecords();
        List<CartVO> cartVOList = BeanUtil.copyToList(cartList, CartVO.class);
        // 处理新价格等数据（直接传递过去修改即可，因为集合数据通过地址存储）
        handleCartItems(cartVOList);
        return Result.success(cartVOList);
    }

    /**
     * 购物车单商品数量加减
     * @param itemId
     * @param num
     * @return
     */
    @Override
    public Result numAdd(Long itemId, Integer num) {
        Long userId = ThreadLocalUtil.get();
        // 检查商品是否存在
        if (!checkItemExist(userId, itemId)) {
            throw new CommonException("该商品不在购物车中");
        }
        //  数量不能小于等于0
        if (num <= 0) {
            throw new CommonException("别找bug了老弟");
        }
        LambdaUpdateWrapper<Cart> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Cart::getUserId, userId)
                .eq(Cart::getItemId, itemId)
                .set(Cart::getCartNum, num);
        try {
            this.update(updateWrapper);
            return Result.success();
        } catch (Exception e) {
            throw new CommonException("商品更新失败", e);
        }
    }

    /**
     * 删除购物车
     * @param id
     * @return
     */
    @Override
    public Result deleteCart(Long id) {
        try {
            this.removeById(id);
            return Result.success();
        } catch (Exception e) {
            throw new CommonException("删除购物车商品失败",e);
        }
    }

    /**
     * 处理购物车数据
     * @param cartVOList
     */
    private void handleCartItems(List<CartVO> cartVOList) {
        List<Long> itemIds = cartVOList.stream().map(CartVO::getItemId).collect(Collectors.toList());
        List<Item> items = itemClient.queryItemsByIds(itemIds);
        // 转换成Map集合，key是id，两种写法都可以
        Map<Long, Item> itemMap = items.stream().collect(Collectors.toMap(Item::getId, item -> item));
//        Map<Long, Item> itemMap = items.stream().collect(Collectors.toMap(Item::getId, Function.identity()));
        // 循环购物车数据，设置新价格等数据
        for (CartVO cartVO : cartVOList) {
            Item item = itemMap.get(cartVO.getItemId());
            if(item == null){
                cartVO.setCartNum(0);
                continue;
            }
            cartVO.setNewPrice(item.getPrice());
            cartVO.setItemName(item.getItemName());
            cartVO.setImageUrl(item.getImageUrl());
            cartVO.setStock(item.getStock());
        }
    }

    /**
     * 检查商品是否存在
     * @param userId
     * @param itemId
     */
    private boolean checkItemExist(Long userId, Long itemId) {
        LambdaQueryWrapper<Cart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Cart::getUserId, userId).eq(Cart::getItemId, itemId);
        long count = this.count(queryWrapper);
        return count > 0;
    }
}
